﻿using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;

namespace uTILLIty.Outlook.FlexFileAddIn
{
	public partial class FilterableFolderList : UserControl, IFilterableFolderList
	{
		private CandidateFolderInfo _selectedItem;

		public FilterableFolderList()
		{
			InitializeComponent();
			BindingSource = new BindingSource();
			FoldersDataGridView.AutoGenerateColumns = false;
			FoldersDataGridView.DataSource = BindingSource;
			FoldersDataGridView.CellFormatting += OnCellFormatting;
		}

		[TypeConverter("System.Windows.Forms.Design.DataSourceConverter, System.Design")]
		[Category("Data")]
		[DefaultValue(null)]
		public object DataSource
		{
			get { return BindingSource.DataSource; }
			set { BindingSource.DataSource = value; }
		}

		[Category("Data")]
		[Editor("System.Windows.Forms.Design.DataMemberListEditor, System.Design",
			"System.Drawing.Design.UITypeEditor, System.Drawing")]
		[DefaultValue("")]
		public string DataMember
		{
			get { return BindingSource.DataMember; }
			set { BindingSource.DataMember = value; }
		}

		public event EventHandler<EventArgs<CandidateFolderInfo>> SelectedItemChanged;
		public event EventHandler<EventArgs<CandidateFolderInfo>> MoveSelectedItems;
		public event EventHandler<EventArgs<CandidateFolderInfo>> OpenFolder;
		public event EventHandler FilterTextChanged;

		public BindingSource BindingSource { get; }

		public CandidateFolderInfo SelectedItem
		{
			get { return _selectedItem; }
			private set
			{
				if (Equals(_selectedItem, value))
					return;
				_selectedItem = value;
				RaiseSelectedItemChanged();
			}
		}

		public string FilterText
		{
			get { return FilterTextBox.Text; }
			set { FilterTextBox.Text = value; }
		}

		public Form ContainingForm
		{
			get
			{
				var f = Parent;
				while (f != null && !(f is Form))
					f = f.Parent;
				return f as Form;
			}
		}

		public void SetStatusText(string text, params object[] args)
		{
			var msg = string.Format(text, args ?? new object[0]);
			if (InvokeRequired)
			{
				Invoke(new ProcessMessage(InternalSetStatusText), msg);
				return;
			}
			InternalSetStatusText(msg);
		}

		public void SetFilterTextboxFocus()
		{
			FilterTextBox.Focus();
		}

		public void ResetSelectedRow()
		{
			FoldersDataGridView.ClearSelection();
		}

		private void InternalSetStatusText(string msg)
		{
			statusInfoLabel.Text = msg ?? "";
		}

		private void RaiseFilterTextChanged()
		{
			if (FilterTextChanged == null)
				return;

			FilterTextChanged.Invoke(this, EventArgs.Empty);
		}

		private void RaiseSelectedItemChanged()
		{
			if (SelectedItemChanged == null)
				return;

			SelectedItemChanged.Invoke(this, new EventArgs<CandidateFolderInfo>(_selectedItem));
		}

		private void RaiseMoveSelection()
		{
			if (!SetSelectedItem())
				return;

			if (MoveSelectedItems == null)
				return;

			MoveSelectedItems.Invoke(this, new EventArgs<CandidateFolderInfo>(_selectedItem));
		}

		private void RaiseOpenFolder()
		{
			if (!SetSelectedItem())
				return;

			if (OpenFolder == null)
				return;

			OpenFolder.Invoke(this, new EventArgs<CandidateFolderInfo>(_selectedItem));
		}

		private bool SetSelectedItem()
		{
			SelectedItem = null;
			if (FoldersDataGridView.SelectedRows.Count != 1)
				return false;

			var fi = FoldersDataGridView.SelectedRows[0].DataBoundItem as CandidateFolderInfo;
			if (fi != null)
			{
				SelectedItem = fi;
				return true;
			}

			return false;
		}

		private void OnKeyDown(object sender, KeyEventArgs e)
		{
			if (FoldersDataGridView.CurrentRow == null || FoldersDataGridView.Rows.Count == 0)
				return;

			var idx = FoldersDataGridView.CurrentRow.Index;
			switch (e.KeyCode)
			{
				case Keys.Down:
					if (idx + 1 < FoldersDataGridView.Rows.Count)
					{
						FoldersDataGridView.CurrentCell = FoldersDataGridView.Rows[idx + 1].Cells[0];
					}
					SetSelectedItem();
					break;
				case Keys.Up:
					if (idx > 0)
					{
						FoldersDataGridView.CurrentCell = FoldersDataGridView.Rows[idx - 1].Cells[0];
					}
					SetSelectedItem();
					break;
				case Keys.Return:
					if (e.Modifiers == Keys.Control)
						RaiseOpenFolder();
					else
						RaiseMoveSelection();
					break;
				default:
					return;
			}
			e.Handled = true;
		}

		private void ShowTip(DataGridViewCell currentCell)
		{
			if (currentCell == null)
				return;
			var pnt = new Point(5, FoldersDataGridView.Top + FoldersDataGridView.Height - 10);
			toolTip1.Show(currentCell.ToolTipText, this, pnt, 5000);
		}

		private void OnRowDoubleClicked(object sender, EventArgs e)
		{
			SetSelectedItem();
		}

		private void OnFilterTextChanged(object sender, EventArgs e)
		{
			RaiseFilterTextChanged();
		}

		private void OnMoveItemsButtonClicked(object sender, EventArgs e)
		{
			RaiseMoveSelection();
		}

		private void OnOpenFolderButtonClicked(object sender, EventArgs e)
		{
			RaiseOpenFolder();
		}

		private void OnFilterTextBoxClicked(object sender, EventArgs e)
		{
			if (FilterTextBox.SelectionLength == 0)
				FilterTextBox.SelectAll();
		}

		private void OnDragGiveFeedback(object sender, GiveFeedbackEventArgs e)
		{
			e.UseDefaultCursors = true;
			//e.Effect = DragDropEffects.Move;
		}

		private void OnDrop(object sender, DragEventArgs e)
		{
			//var data = e.Data.GetData("RenPrivateMessages");
			//var formats = e.Data.GetFormats();
			//Debug.WriteLine("Formats: {0}", string.Join(", ", formats));
		}

		private void OnFormDrop(object sender, DragEventArgs e)
		{
			//var data = e.Data.GetData("RenPrivateMessages");
		}

		private void OnCellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
		{
			var cell = FoldersDataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex];
			var fi = FoldersDataGridView.Rows[e.RowIndex].DataBoundItem as CandidateFolderInfo;
			if (fi == null)
				return;
			cell.ToolTipText = string.Format("{0}\r\n{2} - {1}", fi, fi.CandidateReasonDescription, fi.DisplayPriority);
			cell.Style.ForeColor = fi.ForeColor;
			cell.Style.BackColor = fi.BackColor;
			//if (fi.IsMailBasedCandidate)
			//  cell.Style.BackColor = System.Drawing.Color.Silver;
		}

		private void OnDeleteFilterButtonClicked(object sender, EventArgs e)
		{
			FilterTextBox.Text = string.Empty;
		}

		private void OnSortCompare(object sender, DataGridViewSortCompareEventArgs e)
		{
		}

		private void OnSelectionChanged(object sender, EventArgs e)
		{
			ShowTip(FoldersDataGridView.CurrentCell);
		}

		private delegate void ProcessMessage(string msg);
	}
}